<?php
namespace Leaps\Filesystem;

use FilesystemIterator;

class FileNotFoundException extends \Exception
{
}
class Filesystem
{

    /**
     * 确定文件是否存在
     *
     * @param string $path
     * @return bool
     */
    public function exists($path)
    {
        return file_exists ( $path );
    }

    /**
     * 获取文件内容
     *
     * @param string $path
     * @return string
     */
    public function get($path)
    {
        if ( $this->isFile ( $path ) ) return file_get_contents ( $path );
        throw new FileNotFoundException ( "File does not exist at path {$path}" );
    }

    /**
     * 获取远程文件的内容
     *
     * @param string $path
     * @return string
     */
    public function getRemote($path)
    {
        return file_get_contents ( $path );
    }

    /**
     * 有返回值的文件
     *
     * @param string $path
     * @return mixed
     */
    public function getRequire($path)
    {
        if ( $this->isFile ( $path ) ) return require $path;
        throw new FileNotFoundException ( "File does not exist at path {$path}" );
    }

    /**
     * 加载指定的文件
     *
     * @param string $file
     * @return void
     */
    public function requireOnce($file)
    {
        require_once $file;
    }

    /**
     * 向文件写入内容
     *
     * @param string $path 文件绝对路径
     * @param string $contents 内容
     * @return int
     */
    public function put($path, $contents)
    {
        return file_put_contents ( $path, $contents );
    }

    /**
     * 追加内容到文件
     *
     * @param string $path 文件绝对路径
     * @param string $data 内容
     * @return int
     */
    public function append($path, $data)
    {
        return file_put_contents ( $path, $data, FILE_APPEND );
    }

    /**
     * 删除文件
     *
     * @param string $path 文件绝对路径
     * @return bool
     */
    public function delete($path)
    {
        return @unlink ( $path );
    }

    /**
     * 将一个文件移动到新的位置
     *
     * @param string $path
     * @param string $target
     * @return void
     */
    public function move($path, $target)
    {
        return rename ( $path, $target );
    }

    /**
     * 复制文件到新路径
     *
     * @param string $path
     * @param string $target
     * @return void
     */
    public function copy($path, $target)
    {
        return copy ( $path, $target );
    }

    /**
     * 从路径获取一个文件的扩展名
     *
     * @param string $path
     * @return string
     */
    public function extension($path)
    {
        return pathinfo ( $path, PATHINFO_EXTENSION );
    }

    /**
     * 返回文件类型
     *
     * @param string $path
     * @return string
     */
    public function type($path)
    {
        return filetype ( $path );
    }

    /**
     * 获取文件大小
     *
     * @param string $path
     * @return int
     */
    public function size($path)
    {
        return filesize ( $path );
    }

    public function touch($path,$time,$atime=null){
        return touch($path,$time,$atime);
    }

    /**
     * 获取文件的最后修改时间
     *
     * @param string $path
     * @return int
     */
    public function lastModified($path)
    {
        return filemtime ( $path );
    }

    /**
     * 确定给定的路径是否是一个目录
     *
     * @param string $directory
     * @return bool
     */
    public function isDirectory($directory)
    {
        return is_dir ( $directory );
    }

    /**
     * 确定给定的路径是否是可写的。
     *
     * @param string $path
     * @return bool
     */
    public function isWritable($path)
    {
        return is_writable ( $path );
    }

    /**
     * 确定给定的路径是否是一个文件。
     *
     * @param string $file
     * @return bool
     */
    public function isFile($file)
    {
        return is_file ( $file );
    }

    /**
     * 找到一个给定的模式匹配的路径名称。
     *
     * @param string $pattern
     * @param int $flags
     * @return array
     */
    public function glob($pattern, $flags = 0)
    {
        return glob ( $pattern, $flags );
    }

    /**
     * 得到一个阵列中的一个目录下的所有文件。
     *
     * @param string $directory
     * @return array
     */
    public function files($directory)
    {
        $glob = glob ( $directory . '/*' );
        if ( $glob === false ) return array ();
        return array_filter ( $glob, function ($file)
        {
            return filetype ( $file ) == 'file';
        } );
    }

    /**
     * 创建一个文件夹
     *
     * @param string $path
     * @param int $mode
     * @param bool $recursive
     * @return bool
     */
    public function createDirectory($path, $mode = 0777, $recursive = false)
    {
        return mkdir ( $path, $mode, $recursive );
    }

    /**
     * 从一个位置到另一个复制目录。
     *
     * @param string $directory
     * @param string $destination
     * @param int $options
     * @return void
     */
    public function copyDirectory($directory, $destination, $options = null)
    {
        if ( ! $this->isDirectory ( $directory ) ) return false;
        $options = $options ?  : FilesystemIterator::SKIP_DOTS;
        if ( ! $this->isDirectory ( $destination ) ) {
            $this->makeDirectory ( $destination, 0777, true );
        }
        $items = new FilesystemIterator ( $directory, $options );
        foreach ( $items as $item ) {
            $target = $destination . '/' . $item->getBasename ();
            if ( $item->isDir () ) {
                $path = $item->getPathname ();

                if ( ! $this->copyDirectory ( $path, $target, $options ) ) return false;
            } else {
                if ( ! $this->copy ( $item->getPathname (), $target ) ) return false;
            }
        }
        return true;
    }

    /**
     * 递归删除一个目录。 The directory itself may be optionally preserved.
     *
     * @param string $directory
     * @param bool $preserve
     * @return void
     */
    public function deleteDirectory($directory, $preserve = false)
    {
        if ( ! $this->isDirectory ( $directory ) ) return;
        $items = new FilesystemIterator ( $directory );
        foreach ( $items as $item ) {
            if ( $item->isDir () ) {
                $this->deleteDirectory ( $item->getPathname () );
            } else {
                $this->delete ( $item->getPathname () );
            }
        }
        if ( ! $preserve ) @rmdir ( $directory );
    }

    /**
     * 清空指定目录下的所有文件和文件夹。
     *
     * @param string $directory
     * @return void
     */
    public function cleanDirectory($directory)
    {
        return $this->deleteDirectory ( $directory, true );
    }
}
